package com.cn.jinl.service;

import com.cn.jinl.api.IProcureStorageService;
import com.cn.jinl.dao.ProcureMapper;
import com.cn.jinl.dao.ProcureStorageHisMapper;
import com.cn.jinl.dao.ProcureStorageMapper;
import com.cn.jinl.dao.ProcureStorageOutHisMapper;
import com.cn.jinl.domain.*;
import com.cn.jinl.utils.*;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@Service
public class ProcureStorageServiceImpl implements IProcureStorageService {

    @Autowired
    private ProcureStorageMapper procureStorageMapper;

    @Autowired
    private ProcureStorageHisMapper procureStorageHisMapper;

    @Autowired
    private ProcureStorageOutHisMapper procureStorageOutHisMapper;

    @Autowired
    private ProcureMapper procureMapper;

    @Autowired
    private GenerateUUID generateUUID;

    @Override
    public List<ProcureStorage> getProcureStorageList(QueryForm queryForm) throws Exception {
        int count = procureStorageMapper.selectProcureStorageListCount(queryForm);
        if(count == 0){
            return Lists.newArrayList();
        }
        List<ProcureStorage> procureStorages = procureStorageMapper.selectProcureStorageList(queryForm);
        procureStorages.get(0).setCount(count);
        return procureStorages;
    }

    @Override
    public List<ProcureStorage> getProcureStorageDetailList(QueryForm queryForm) throws Exception {
        List<ProcureStorage> list = procureStorageMapper.selectProcureStorageDetailList(queryForm);
        if(CollectionUtils.isEmpty(list)){
            return list;
        }
        List<ProcureStorageOutHis> hasOuts = procureStorageOutHisMapper.selectHasOutStorages();
        Map<String,Double> outMaps = Maps.newHashMap();
        for(ProcureStorageOutHis procureStorageOutHis:hasOuts){
            String materialId = procureStorageOutHis.getMaterialId();
            outMaps.put(materialId,Double.parseDouble(procureStorageOutHis.getOutCount()));
        }
        Iterator<ProcureStorage> iterator = list.iterator();
        while (iterator.hasNext()){
            ProcureStorage procureStorage = iterator.next();
            String procureCount = procureStorage.getProcureCount();
            String procureExistCount = procureStorage.getProcureExistCount();
            String storageCountStatus = "3";
            double outCount = 0;
            if(outMaps.containsKey(procureStorage.getMaterialId())){
                outCount = outMaps.get(procureStorage.getMaterialId());
            }
            if(StringUtils.isNotEmpty(procureCount)&&StringUtils.isNotEmpty(procureExistCount)){
                double count1 = Double.parseDouble(procureCount);
                double count2 = Double.parseDouble(procureExistCount) - outCount;
                if(count1 > 0 && count2 > 0){
                    double percent = count2 / count1;
                    if(percent > 0.3 && percent < 0.5){
                        storageCountStatus = "2";
                    }else if(percent >=0.5){
                        storageCountStatus = "1";
                    }
                }
                double inCount = Double.parseDouble(procureExistCount);
                double left =inCount - outCount;
                procureStorage.setProcureExistCount(NumberUtil.getPoint(left,2));
            }
            procureStorage.setStorageCountStatus(storageCountStatus);
            if(StringUtils.isNotEmpty(queryForm.getStorageCountStatus())){
                if(!StringUtils.equals(queryForm.getStorageCountStatus(),storageCountStatus)){
                    iterator.remove();
                }
            }
        }
        return list;
    }

    @Override
    public List<ProcureStorageHis> getProcureStorageHistoryList(String id) throws Exception {
        if(StringUtils.isEmpty(id)){
            return Lists.newArrayList();
        }

        List<ProcureStorageHis> procureStorageHis = procureStorageHisMapper.selectProcureStorageHisList(id);
        return procureStorageHis;
    }

    @Override
    public List<ProcureStorageHis> getProcureStorageHistoryListByPid(String id) throws Exception {
        if(StringUtils.isEmpty(id)){
            return Lists.newArrayList();
        }

        List<ProcureStorageHis> procureStorageHis = procureStorageHisMapper.selectProcureStorageHisListByPid(id);
        return procureStorageHis;
    }

    @Override
    public String batchAddProcureStorages(List<ProcureStorage> procureStorages) throws Exception {
        if(CollectionUtils.isEmpty(procureStorages)){
            return "参数异常！";
        }
        for(ProcureStorage procureStorage:procureStorages){
            procureStorage.setId(CommonUtil.generateRandomNum("prostorage-"));
        }
        int count = procureStorageMapper.batchInsertProcureStorages(procureStorages);
        return CommonUtil.outStr(count);
    }

    @Override
    public String batchInsertProcureStorageHis(List<ProcureStorageHis> procureStorageHis) throws Exception {
        if(CollectionUtils.isEmpty(procureStorageHis)){
            return "参数异常！";
        }
        String procureId = procureStorageHis.get(0).getProcureId();
        Procure exist = procureMapper.selectByPrimaryKey(procureId);
        if(null == exist){
            return "任务不存在";
        }
        if(!StringUtils.equals(exist.getProcureStatus(),"0")&&!StringUtils.equals(exist.getProcureStatus(),"1")){
            return "任务不在进行中，无法入库";
        }
        List<ProcureStorageHis> exists = this.getProcureStorageHistoryListByPid(procureId);
        Map<String,Double> relateMap = Maps.newHashMap();
        if(!CollectionUtils.isEmpty(exists)){
            for(ProcureStorageHis his : exists){
                String procureStorageId = his.getProcureStorageId();
                double storageCount = Double.parseDouble(his.getStorageCount());
                if(relateMap.containsKey(procureStorageId)){
                    relateMap.put(procureStorageId,relateMap.get(procureStorageId)+storageCount);
                }else{
                    relateMap.put(procureStorageId,storageCount);
                }
            }
        }
        List<ProcureStorage> updateProcureStorageList = Lists.newArrayList();
        boolean procureStatus = true;
        for(ProcureStorageHis storageHis:procureStorageHis){
            double storageCount = Double.parseDouble(storageHis.getStorageCount());
            double storageTotalCount =  Double.parseDouble(storageHis.getStorageTotalCount());
            ProcureStorage storage = new ProcureStorage();
            storage.setId(storageHis.getProcureStorageId());
            if(relateMap.containsKey(storageHis.getProcureStorageId())){
                double existCount = relateMap.get(storageHis.getProcureStorageId());
                if(storageCount + existCount > storageTotalCount){
                    return "入库数量大于总库存！";
                }
                storage.setProcureExistCount((storageCount + existCount)+"");
                if(storageCount + existCount == storageTotalCount){
                    storage.setStorageStatus("2");
                    procureStatus = procureStatus&&true;
                }else{
                    storage.setStorageStatus("1");
                    procureStatus = procureStatus&&false;
                }
            }else{
                storage.setProcureExistCount(storageHis.getStorageCount());
                if(storageCount  == storageTotalCount){
                    storage.setStorageStatus("2");
                    procureStatus = procureStatus&&true;
                }else{
                    storage.setStorageStatus("1");
                    procureStatus = procureStatus&&false;
                }
            }
            updateProcureStorageList.add(storage);
        }
        String status = procureStatus?"2":"1";
        Procure update = new Procure();
        update.setId(procureId);
        update.setProcureStatus(status);
        int count = procureMapper.updateByPrimaryKeySelective(update);
        if(count < 0){
            return "更新采购任务表异常！";
        }

        for(ProcureStorageHis his:procureStorageHis){
            String key = "RK"+generateUUID.getYearMoth();
            int num = generateUUID.getNumberFlag(key);
            String code = key+generateUUID.getThreeNumStr(num);
            his.setProcureStorageCode(code);
        }
        count = procureStorageHisMapper.batchInsertProcureStorageHis(procureStorageHis);
        if(count > 0){
            count = procureStorageMapper.batchUpdateProcureStorageStatus(updateProcureStorageList);
            if(count < 0){
                throw new Exception("更新表异常！");
            }
        }
        return CommonUtil.outStr(count);
    }

    @Override
    public int getProcureStorageWaitingCount() throws Exception {
        ProcureStorageExample example = new ProcureStorageExample();
        example.createCriteria().andStatusEqualTo(Constants.NORMAL_STATUS).andStorageStatusEqualTo("0");
        return procureStorageMapper.countByExample(example);
    }

    @Override
    public String updateProcureStorageStatusByProcId(String procureId,String status) {
        ProcureStorageExample procureStorageExample = new ProcureStorageExample();
        procureStorageExample.createCriteria().andProcureIdEqualTo(procureId);
        ProcureStorage storageUpdate = new ProcureStorage();
        storageUpdate.setStorageStatus(status);
        int count = procureStorageMapper.updateByExampleSelective(storageUpdate,procureStorageExample);
        return CommonUtil.outStr(count);
    }


    @Override
    public List<ProcureStorage> getAPIProcureStorageListById(String id) throws Exception {
        return procureStorageMapper.selectProcureStorageByProcureId(id);
    }

    @Override
    public List<ProcureVo> getProcureStorageListByMaterialCode(QueryForm queryForm) throws Exception {
        String year = queryForm.getYear();
        String startTime = year+"-01-01";
        String endTime = year+"-12-31 23:59:59";
        queryForm.setStartTime(startTime);
        queryForm.setEndTime(endTime);
        List<ProcureStorage> procureStorages = procureStorageMapper.selectProcureStorageListByMaterialCode(queryForm);
        Map<String,List<ProcureStorage>> listMap  =Maps.newHashMap();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
        for(ProcureStorage storage :procureStorages){
            String yearMoth = simpleDateFormat.format(storage.getCreateTime());
            if(listMap.containsKey(yearMoth)){
                listMap.get(yearMoth).add(storage);
            }else{
                List<ProcureStorage> storages = Lists.newArrayList();
                storages.add(storage);
                listMap.put(yearMoth,storages);
            }
        }
        List<ProcureVo> procureVos = Lists.newLinkedList();
        for(int i = 1 ; i <=12;i++){
            String key = year+"-"+(i <10?("0"+i):i);
            ProcureVo procureVo = new ProcureVo();
            procureVo.setYearMoth(key);
            if(listMap.containsKey(key)){
                List<ProcureStorage> existStorages =  listMap.get(key);
                procureVo.setProcureCount(existStorages.size()+"");
                double count = 0.0;
                double price = 0.0;
                double max = 0.0;
                double min = Double.parseDouble(existStorages.get(0).getProcureTotalPrice());
                for(ProcureStorage ps:existStorages){
                    count+= Double.parseDouble(ps.getProcureCount());
                    if(!StringUtils.isEmpty(ps.getProcureTotalPrice())){
                        price+=Double.parseDouble(ps.getProcureTotalPrice());
                        if(Double.parseDouble(ps.getProcurePrice()) > max){
                            max = Double.parseDouble(ps.getProcurePrice());
                        }
                        if(Double.parseDouble(ps.getProcurePrice()) < min){
                            min = Double.parseDouble(ps.getProcurePrice());
                        }
                    }
                }
                double dist = max - min;
                double average = price/existStorages.size();
                procureVo.setProcureCount(existStorages.size()+"");
                procureVo.setTotal(count+"");
                procureVo.setMaxPrice(max+"");
                procureVo.setMinPrice(min+"");
                procureVo.setPrice(NumberUtil.getPoint(price,1));
                procureVo.setAveragePrice(NumberUtil.getPoint(average,1));
                procureVo.setDistPrice(NumberUtil.getPoint(dist,1));
            }
            procureVos.add(procureVo);
        }
        return procureVos;
    }

}
